home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
s44play
/
s44p101s.lzh
/
cdxa.s
< prev
next >
Wrap
Text File
|
2000-01-24
|
90KB
|
3,529 lines
.include doscall.mac
.include scsiconst.equ
.include global.mac
.include preconv.mac
;----------------------------------------------------------------
;CDXA(Compact Disc eXtended Architecture)
MAX_PATH_TABLE_LENGTH equ 2048*8 ;パステーブルの最大サイズ(2048の倍数)
MAX_DIRECTORY_LENGTH equ 2048*8 ;1個のディレクトリの最大サイズ(2048の倍数)
;↑これらは本来,サイズがわかった時点で必要な領域をアロケートするべき
;(-onmemのときバッファを目一杯確保してしまうと他の領域をアロケートできなくなるので注意)
;----------------------------------------------------------------
;----------------------------------------------------------------
;ISO9660のディレクトリ情報レコード
.offset 0
iso9660_dir_len: .ds.b 1 ;$0000 ディレクトリレコードの長さ
iso9660_dir_xarlen: .ds.b 1 ;$0001 XARの長さ
iso9660_dir_pos_l: .ds.l 1 ;$0002 セクタ番号(little-endian)
iso9660_dir_pos_b: .ds.l 1 ;$0006 セクタ番号(big-endian)
iso9660_dir_len_l: .ds.l 1 ;$000A 長さのバイト数(little-endian)
iso9660_dir_len_b: .ds.l 1 ;$000E 長さのバイト数(big-endian)
;ここからタイムスタンプ
iso9660_dir_date:
iso9660_dir_year: .ds.b 1 ;$0012 西暦年-1900(0~255)
iso9660_dir_month: .ds.b 1 ;$0013 月(1~12)
iso9660_dir_day: .ds.b 1 ;$0014 日(1~31)
iso9660_dir_hour: .ds.b 1 ;$0015 時(0~23)
iso9660_dir_time:
iso9660_dir_minute: .ds.b 1 ;$0016 分(0~59)
iso9660_dir_second: .ds.b 1 ;$0017 秒(0~60)
iso9660_dir_diff: .ds.b 1 ;$0018 偏差(15秒単位,0~95)
iso9660_dir_file_flag: .ds.b 1 ;$0019 ファイルフラグ
iso9660_dir_unit_size: .ds.b 1 ;$001A ファイルユニットのサイズ
iso9660_dir_gap_size: .ds.b 1 ;$001B インタリーブギャップのサイズ
iso9660_dir_vol_num_l: .ds.w 1 ;$001C ボリュームの通し番号(little-endian)
iso9660_dir_vol_num_b: .ds.w 1 ;$001E ボリュームの通し番号(big-endian)
iso9660_dir_name_len: .ds.b 1 ;$0020 ファイル識別子の長さ
iso9660_dir_name: ;$0021 ファイル識別子
;ここで偶数整合すること(隙間は$00で埋める)
;CD-Extraのディレクトリ情報レコードの拡張部分
;(ファイル識別子の直後の偶数整合の直後から)
.offset 0
.ds.b 6 ;$0000
.ds.b 2 ;$0006 'XA'($58,$41)
.ds.b 1 ;$0008 $00=2048bytes/sector,$01=2336bytes/sector
.ds.b 5 ;$0009
.text
;----------------------------------------------------------------
;指定されたファイルがCDXAかどうか調べる
; フルパスに変換する
; fullpath
; ドライブ番号を確認する
; アクセスできるかどうか確認する
; DRVCTRL
; SCSI-IDを確認する
; get_scsiid
; CD-ROMドライブかどうか確認する
; get_scsi_device_type
; TOCを取得する
; get_track_info
; データトラックの先頭セクタ番号を確認する
; データトラックの先頭+16のセクタをMode2 form1(2048bytes/sector)で読み込む
; (density=$81,size=$0800)
; +$0001~'CD001'(ISO9660識別子)を確認
; +$0400~'CD-XA001'(CD-Extra識別子)を確認
; +$0094~M型パステーブルの位置(絶対セクタ番号)を得る
; M型パステーブルを読み込む
; M型パステーブルを辿って目的のファイルがあるディレクトリの先頭セクタ番号を得る
; ディレクトリセクタを読み込む
; ディレクトリの占有セクタ数の確認方法は?
; →ディレクトリの先頭に自分自身を指す情報があるのでそれを使う
; ディレクトリから目的のファイルを探す
; ファイル名の後ろに';1'が付いている場合があるので注意
; CDXAであることを確認する
; システム使用領域の先頭+6から3バイトが
; $58(X),$41(A),$00 普通のファイル
; $58(X),$41(A),$01 XAなファイル
; ファイルの先頭セクタ番号とセクタ数を返す
; ファイルの占有セクタ数の確認方法は?
; →ファイルサイズが2048bytes/sector換算の値(2048の倍数)で入って
; いるのでファイルサイズを2048で割ればセクタ数が求まる
;ファイルはMode2 form2(2336bytes/sector)で読み込むこと
; (density=$81,size=$920)
;<a0.l:ファイル名の先頭
;>d0.l:先頭セクタ番号(絶対セクタ番号),-1=エラー
;>d1.l:セクタ数
.text
.align 4,$2048
is_cdxa_file::
movem.l d1-d7/a0-a6,-(sp)
;フルパスに変換する
movea.l a0,a1
lea.l cdxa_fullpath_buffer,a0
bsr fullpath
bmi 90f
;ドライブ番号を確認する
moveq.l #$1F,d7
and.b (a0),d7 ;d7=ドライブ番号(1=A:)
.if 0
;アクセスできるかどうか確認する
move.w d7,-(sp)
DOS _DRVCTRL
addq.l #2,sp
tst.l d0
bmi 90f ;ドライブ番号が不正
moveq.l #%00000010,d1
and.b d0,d1
beq 90f ;メディアがセットされていない
moveq.l #%00000101,d1
and.b d0,d1
bne 90f ;メディアの準備ができていない
.endif
;SCSI-IDを確認する
move.l d7,d0
bsr get_scsiid
bmi 90f ;SCSIドライブではない
move.l d0,cdxa_scsiid
;CD-ROMドライブかどうか確認する
move.l cdxa_scsiid,scsiid
move.l scsiid,d0
bsr get_scsi_device_type
bmi 90f ;念のため
cmp.b #SCSI_TYPE_CDROM,d0
bne 90f ;CD-ROMドライブではない
;CD-ROMの準備
bsr init_cdrom
bmi 90f ;メディアにアクセスできない
;データトラックの先頭セクタ番号を確認する
lea.l cdda_trkinf,a2 ;トラック情報レコード
move.l cdda_mintrk,d0 ;先頭のトラック番号が1よりも大きかった場合に対応
subq.b #1,d0 ;(念のため)
mulu.w #trkinf_record_size,d0
lea.l (a2,d0.l),a2 ;cdda_mintrkのトラック情報レコードの先頭
move.l cdda_mintrk,d6 ;開始トラック番号
10: tst.b (trkinf_dattrk,a2) ;-1=データトラック
bne 11f
lea.l (trkinf_record_size,a2),a2
addq.b #1,d6
cmp.l cdda_maxtrk,d6
bls 10b
bra 90f ;データトラックが見つからない
11:
move.l (trkinf_topfrm,a2),d5 ;d5=データトラックの先頭セクタ番号
move.l d5,sector_dattrk_top
;データトラックの先頭+16のセクタをMode2 form1で読み込む
moveq.l #16,d0
add.l d5,d0 ;データトラックの先頭+16
moveq.l #1,d1 ;セクタ数
lea.l cdrom_volume_buffer,a0
bsr read_cdrom_mode2_2048 ;基本ボリュームを読み込む
bmi 90f
.if 0
lea.l cdrom_volume_buffer,a0
.rept 16
moveq.l #' ',d0
bsr eputchar
move.b (a0)+,d0
bsr h2tos_eprint
.endm
.endif
lea.l cdrom_volume_buffer,a2 ;基本ボリュームの先頭
; +$0001~'CD001'(ISO9660識別子)を確認
lea.l (0,a2),a0
cmpi.l #$01434430,(a0)+ ;$01,'CD0'
bne 90f
cmpi.l #$30310100,(a0)+ ;'01',$01,$00
bne 90f
; +$0400~'CD-XA001'(CD-Extra識別子)を確認
lea.l ($0400,a2),a0
cmpi.l #'CD-X',(a0)+
bne 90f
cmpi.l #'A001',(a0)+
bne 90f
; +$0094~M型パステーブルの位置(絶対セクタ番号)を得る
move.l ($0088,a2),d3 ;d3=パステーブルのサイズ
cmp.l #MAX_PATH_TABLE_LENGTH,d3
bhi 90f ;パステーブルが大きすぎる
move.l ($0094,a2),d6 ;d6=M型パステーブルの絶対セクタ番号
;M型パステーブルを読み込む
move.l d6,d0 ;セクタ番号
move.l d3,d1 ;パステーブルのバイト数
add.l #2047,d1
lsr.l #8,d1
lsr.l #3,d1 ;セクタ数
lea.l path_table_buffer,a0
bsr read_cdrom_mode2_2048
bmi 90f ;パステーブルを読み込めない
sf.b (a0,d3.l) ;念のためエンドコードを埋め込んでおく
;M型パステーブルを辿って目的のファイルがあるディレクトリの先頭セクタ番号を得る
lea.l cdxa_fullpath_buffer+3,a2 ;サブディレクトリの先頭
lea.l path_table_buffer,a3 ;M型パステーブルの先頭
moveq.l #1,d3 ;親ディレクトリの通し番号(ルートの親はルート)
move.l (2,a3),d4 ;ルートディレクトリのセクタ番号
lea.l (1+1+4+2+1+1,a3),a3 ;ルートディレクトリはスキップ
moveq.l #2,d2 ;ディレクトリの通し番号
20:
;<d2.w:現在のディレクトリの通し番号
;<d3.w:親ディレクトリの通し番号
;<d4.l:親ディレクトリのセクタ番号
;<a3.l:ディレクトリレコードの先頭
moveq.l #'/',d0
movea.l a2,a0
bsr strchr
bmi 24f ;ディレクトリ終わり
lea.l (1,a2,d0.l),a2 ;'/'の直後まで進めておく
;<d0.l:検索するディレクトリ名の長さ
;<a0.l:検索するディレクトリ名(エンドコードなし)
21: moveq.l #0,d1
move.b (a3),d1 ;ディレクトリ名の長さ(0=終了)
beq 90f ;ディレクトリが見つからない
cmp.b d1,d0
bne 22f ;ディレクトリ名の長さが一致しないのでスキップ
cmp.w (6,a3),d3
bne 22f ;親ディレクトリの通し番号が一致しないのでスキップ
lea.l (8,a3),a1
bsr strncmpi
beq 23f ;一致した
22: addq.w #1,d1 ;偶数に切り上げる
and.w #$FFFE,d1
lea.l (8,a3,d1.l),a3 ;次のディレクトリレコードへ
addq.w #1,d2 ;ディレクトリの通し番号
bra 21b ;次のディレクトリレコードへ
23: move.w d2,d3 ;ディレクトリの通し番号
move.l (2,a3),d4 ;ディレクトリのセクタ番号
addq.w #1,d1 ;ディレクトリ名の長さを偶数に切り上げる
and.w #$FFFE,d1
lea.l (8,a3,d1.l),a3 ;次のディレクトリレコードへ
addq.w #1,d2 ;ディレクトリの通し番号
bra 20b
24:
;<d4.l:ディレクトリのセクタ番号
;<a2.l:主ファイル名の先頭
;ディレクトリセクタを読み込む
; ディレクトリの占有セクタ数の確認方法は?
; →ディレクトリの先頭に自分自身を指す情報があるのでそれを使う
move.l d4,d0
moveq.l #1,d1 ;とりあえず1セクタだけ読み込む
lea.l directory_buffer,a0
bsr read_cdrom_mode2_2048
bmi 90f ;ディレクトリを読み込めない
move.l directory_buffer+14,d1 ;ディレクトリのサイズ
cmp.l #MAX_DIRECTORY_LENGTH,d1
bhi 90f ;ディレクトリが大きすぎる
move.l d4,d0
addq.l #1,d0 ;次のディレクトリから
add.l #2047,d1 ;ディレクトリのサイズを2048の倍数に切り上げる
lsr.l #8,d1
lsr.l #3,d1
subq.l #1,d1
bls @f ;最初に読んだ1セクタに収まっている
lea.l directory_buffer+2048,a0
bsr read_cdrom_mode2_2048 ;ディレクトリの残りを読み込む
bmi 90f ;ディレクトリを読み込めない
@@:
;ディレクトリから目的のファイルを探す
; ファイル名の後ろに';1'が付いている場合があるので注意
;<a2.l:主ファイル名の先頭
lea.l directory_buffer,a3
movea.l a2,a0
bsr strlen
;<d0.l:ファイル名の長さ
;<a0.l:ファイル名
;<a3.l:ディレクトリレコード
30: moveq.l #0,d3
move.b (a3),d3 ;ディレクトリレコードの長さ
moveq.l #$02,d1 ;とりあえずディレクトリ属性だけ除外
and.b (iso9660_dir_file_flag,a3),d1
bne 31f ;ディレクトリだった
lea.l (iso9660_dir_name_len,a3),a1 ;ファイル名の長さの位置
moveq.l #0,d1
move.b (a1)+,d1 ;ファイル名の長さ
cmp.b d0,d1
blo 31f ;ファイル名が短すぎる
bsr strncmpi
bne 31f ;一致しない
subq.l #1,a1 ;最後に比較した位置の直後
tst.b (a1)
beq 32f ;一致しない
cmpi.b #';',(a1)+
bne 31f ;';1'がないので一致しない
cmpi.b #'1',(a1)+
bne 31f ;';1'がないので一致しない
tst.b (a1)
beq 32f ;';1'があって一致した
31: adda.l d3,a3
tst.b (a3)
bne 30b ;次のディレクトリレコード
bra 90f ;ファイルが見つからない
32: add.w #iso9660_dir_name+1,d1 ;ディレクトリレコードの先頭から
;識別子の末尾までの長さを,偶数に切り上げる
and.w #$FFFE,d1
;<a3.l:ディレクトリレコードの先頭
;<d1.l:ディレクトリレコードの先頭から識別子の末尾までの長さを偶数に切り上げた値
;<d3.l:ディレクトリレコードの長さ
; d3からd1を引いた値がシステム使用領域の長さ
;CDXAであることを確認する
; システム使用領域の先頭+6から3バイトが
; $58(X),$41(A),$00 普通のファイル
; $58(X),$41(A),$01 XAなファイル
move.w d3,d0
sub.w d1,d0
cmp.w #9,d0
blo 90f ;システム使用領域が短すぎる
lea.l (6,a3,d1.l),a0 ;'XA'があるべき位置
cmp.w #'XA',(a0)+
bne 90f ;CDXAのファイルではない
cmpi.b #$01,(a0)
bne 90f ;CDXAのファイルではない
;ファイルの先頭セクタ番号とセクタ数を返す
; ファイルの占有セクタ数の確認方法は?
; →ファイルサイズが2048bytes/sector換算の値(2048の倍数)で入って
; いるのでファイルサイズを2048で割ればセクタ数が求まる
move.l (iso9660_dir_pos_b,a3),d0 ;ファイルの先頭セクタ番号
move.l (iso9660_dir_len_b,a3),d1 ;ファイルサイズ
;(2048byte/sector換算のサイズ)
add.l #2047,d1 ;念のため2048の倍数に切り上げる
lsr.l #8,d1
lsr.l #3,d1 ;セクタ数
98: addq.l #4,sp ;d1の元の値を捨てる
tst.l d0
movem.l (sp)+,d2-d7/a0-a6
rts
99: movem.l (sp)+,d1-d7/a0-a6
rts
90: bsr tini_cdrom
moveq.l #-1,d0
movem.l (sp)+,d1-d7/a0-a6
rts
.data
.align 4
cdxa_scsiid: .dc.l -3 ;CDXAファイルのあるCD-ROMドライブのSCSI-ID
.bss
.align 4
sector_dattrk_top: .ds.l 1 ;データトラックの先頭セクタ番号
cdxa_fullpath_buffer: .ds.b 256 ;フルパスに変換したファイル名
.align 4
cdrom_volume_buffer: .ds.b 2048 ;基本ボリューム
.align 4
path_table_buffer: ;M型パステーブル
directory_buffer: ;ディレクトリ
.if MAX_PATH_TABLE_LENGTH>=MAX_DIRECTORY_LENGTH
.ds.b MAX_PATH_TABLE_LENGTH+2
.else
.ds.b MAX_DIRECTORY_LENGTH+2
.endif
;----------------------------------------------------------------
;CDXAをオープンする
;<current_param_ptr.l:パラメータバッファのアドレス
;>next_param_ptr.l:次のパラメータバッファのアドレス
;>d0.l:負数=エラー,0=データなし正常終了,その他=データあり
;>n-flag:mi=エラー
;>z-flag:eq=データなし正常終了
.text
.align 4,$2048
open_cdxa::
movem.l d1-d7/a0-a6,-(sp)
.if 0
move.l cdxa_scsiid,scsiid
bsr init_cdrom
bmi 99f
.endif
movea.l current_param_ptr,a2
lea.l (pb_size,a2),a0
move.l a0,next_param_ptr
move.l (pb_cdxa_start,a2),d0 ;CDXAファイルの先頭セクタ番号
move.l (pb_cdxa_length,a2),d1 ;CDXAファイルのセクタ数
move.l d0,cdxa_cursec ;現在のセクタ番号
move.l d1,cdxa_rstsec ;残りセクタ数
move.l (pb_trktop,a2),d4 ;開始トラック番号
bpl @f
moveq.l #0,d4
@@: cmp.l #255,d4
bhi 90f ;開始トラック番号が異常
move.l (pb_trkbtm,a2),d5 ;終了トラック番号
bmi 90f ;終了トラック番号が異常
cmp.l #255,d5
bls @f
move.l #255,d5
@@:
;トラックテーブルを初期化する
lea.l cdxa_track_table,a0
moveq.l #-1,d0
move.w #256-1,d1
1: move.l d0,(a0)+ ;セクタヘッダのコピー
move.l d0,(a0)+ ;開始セクタ番号
dbra d1,1b
;指定されたトラックを探す
move.l cdxa_cursec,d2
move.l cdxa_rstsec,d3
cmp.l d4,d5
blt 25f ;パラメータの範囲はチェック済みなので開始>終了はあり得ないが,
;トラック番号の範囲指定があって再生が終了している場合がある
moveq.l #32-1,d6 ;先頭から32トラック以内になければ諦める
1:
move.l d2,d0
moveq.l #1,d1
lea.l cdxa_search_buffer,a0
bsr read_cdrom_mode2_2336
bmi 90f
cmpi.b #$64,(2,a0)
bne 2f ;音声トラックではない
cmp.b (1,a0),d4
bhi 2f ;トラック番号が小さすぎる
cmp.b (1,a0),d5
bhs 3f ;トラック番号が範囲内
2: addq.l #1,d2
subq.l #1,d3
dbeq d6,1b
;指定された範囲の番号のトラックが存在しない
tst.b (pb_done,a2)
bne @f ;再生済みのCDXAファイル
;未再生のCDXAファイル
lea.l (m_cdxa_track_not_found,pc),a0
bsr eaprintcrlf
bra 90f ;再生できなかったのでエラー
@@:
;再生済みのCDXAファイル
25: tst.b (pb_files,a2)
beq 98f ;次のパラメータへ
sf.b (pb_done,a2)
sf.b (pb_is_cdxa,a2) ;_NFILESに戻す
move.l a2,next_param_ptr
bra 98f ;ワイルドカードに含まれる次のファイルへ
3:
;トラックが見つかった
move.l d2,cdxa_cursec ;現在のセクタ番号
move.l d3,cdxa_rstsec ;残りセクタ数
; lea.l cdxa_search_buffer,a0
; moveq.l #0,d4
move.b (1,a0),d4 ;今回再生するトラック番号
move.l d4,d0
addq.l #1,d0
move.l d0,(pb_trktop,a2) ;開始トラック番号を修正する
move.l a2,next_param_ptr ;同じパラメータを繰り返す
move.l (a0),d0 ;セクタヘッダ
move.l d0,cdxa_curhed
moveq.l #MXA4,d6
btst.l #0,d0
beq @f
moveq.l #SXA4,d6
@@:
move.l #37800,d7
btst.l #2,d0
beq @f
move.l #18900,d7
@@:
move.w d6,data_format ;データのフォーマット
move.l d7,data_frequency ;データのサンプリング周波数
tst.b silent_flag
bne 1f
lea.l (m_cdxa_play_0,pc),a0
bsr eprint
lea.l cdxa_fullpath_buffer,a0
bsr eprint
lea.l (m_cdxa_play_1,pc),a0
bsr eprint
move.l d4,d0
bsr utos_eprint
lea.l (m_cdxa_play_2,pc),a0
bsr eprint
move.l cdxa_curhed,d0
bsr h8tos_eprint
lea.l (m_cdxa_play_3p,pc),a0
tst.b conv_flag
beq @f
lea.l (m_cdxa_play_3c,pc),a0
@@: bsr eprintcrlf
1:
bsr init_cdxa_tables ;CDXAデコーダが使用するテーブルの初期化
bmi 90f
clr.l left1
clr.l left2
clr.l right1
clr.l right2
moveq.l #1,d0 ;データあり
bra 99f
98: moveq.l #0,d0 ;データなし正常終了
99: movem.l (sp)+,d1-d7/a0-a6
rts
90: moveq.l #-1,d0
bra 99b
m_cdxa_play_0: .dc.b "CDXA ファイル `",0
m_cdxa_play_1: .dc.b "' のトラック ",0
m_cdxa_play_2: .dc.b ' ($',0
m_cdxa_play_3p: .dc.b ') を再生します',0
m_cdxa_play_3c: .dc.b ') を変換します',0
m_cdxa_track_not_found: .dc.b '指定されたトラックが見つかりません',0
.bss
.align 4
cdxa_cursec: .ds.l 1 ;現在のセクタ番号
cdxa_rstsec: .ds.l 1 ;残りセクタ数
cdxa_curhed: .ds.l 1 ;現在のセクタヘッダ
.align 4
cdxa_track_table: .ds.l 2*256
cdxa_search_buffer: .ds.b 2336
;----------------------------------------------------------------
;CDXAから読み込む
;<a0.l:出力バッファの先頭
;<a1.l:入力バッファの先頭
;>d0.l:データのサイズ,-1=エラー
.text
.align 4,$2048
read_cdxa::
movem.l d1-d7/a0-a6,-(sp)
move.l a0,a4 ;出力バッファの先頭
move.l a1,a5 ;入力バッファの先頭
20: move.l cdxa_rstsec,d0 ;残りセクタ数
beq 99f
move.l cdxa_cursec,d0 ;開始セクタ番号
move.l buffrm,d1 ;バッファのセクタ数
move.b read_shift_count,d4
lsr.l d4,d1 ;セクタ数
cmp.l cdxa_rstsec,d1
bls @f
move.l cdxa_rstsec,d1
@@: add.l d1,cdxa_cursec
sub.l d1,cdxa_rstsec
movea.l a5,a0 ;入力バッファの先頭
bsr read_cdrom_mode2_2336
bmi 90f
move.w d1,d5
mulu.w #2336,d5 ;入力データのバイト数
lea.l (a5,d5.l),a2 ;入力データの末尾
;バッファ内に該当するセクタが少なくとも1つは存在することを確認する
;(1つもないとpreconv_routineで困る)
movea.l a5,a1 ;入力データの先頭
move.l cdxa_curhed,d0
subq.w #1,d1 ;入力セクタ数-1
bra 2f
1: lea.l (2336,a1),a1
2: cmp.l (a1),d0
dbeq d1,1b
beq 3f
;該当するセクタが1つもないので続きを読み込む
tst.b tab_aborted
bne 91f ;TABが押された
tst.b silent_flag
bne 20b
bsr eputrotor
bra 20b
3:
;a1からa2までを中間バッファにデコードしながらfmpに変換してa4へ
movea.l a4,a0 ;出力バッファの先頭
* movea.l a1,a1 ;入力データの先頭
* movea.l a2,a2 ;入力データの末尾+1
movea.l preconv_routine,a6 ;PCMデータをOPMのTLの並びに変換する
jsr (a6)
move.l a0,d0 ;出力データの末尾+1
sub.l a1,d0 ;出力データの長さ
beq 99f
tas.b (-1,a0) ;エンドコードを付加する
smi.b d1
neg.b d1
sf.b (a0)
move.b d1,(1,a0) ;0,1(末尾のデータのbit7の値)
move.l a1,nxttop
99: bsr eclearrotor
tst.l d0
movem.l (sp)+,d1-d7/a0-a6
rts
90: moveq.l #-1,d0
bra 99b
91: sf.b tab_aborted
moveq.l #0,d0
bra 99b
;----------------------------------------------------------------
.text
.align 4,$2048
close_cdxa::
bsr tini_cdrom
moveq.l #0,d0
rts
;----------------------------------------------------------------
.text
.align 4,$2048
get_restsize_cdxa::
move.l cdxa_rstsec,d0
mulu.w #2336,d0
rts
;----------------------------------------------------------------
;----------------------------------------------------------------
;CDXAデータの前処理(CDXAデータをOPMのTLの並びに変換する)
;<a0.l:出力バッファの先頭
;<a1.l:入力データの先頭(該当するセクタの先頭)
;<a2.l:入力データの末尾+1
;>a0.l:出力データの末尾+1
;>a1.l:出力データの先頭
;?d1-d7/a2-a6
.text
;ステレオ→ステレオ
START_PRECONV_BUFFER .macro side
movem.l d0/a0-a1,-(sp)
lea.l cdxa2pcm_buffer,a0
move.l cdxa2pcm_src_top_ptr,a1 ;最初なので必ず該当するセクタになっている
.if side=1
;ステレオ左
bsr decode_cdxa_stereo_left
.else
;ステレオ右
bsr decode_cdxa_stereo_right
.endif
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0/a0-a1
lea.l cdxa2pcm_buffer,Asrc
lea.l (4032,Asrc),Alim
movea.l cdxa2pcm_dst_top_ptr,Adst
.endm
LOOP_PRECONV_BUFFER .macro side
movem.l d0-d1/a0-a1,-(sp)
move.l cdxa2pcm_src_cur_ptr,a1
move.l cdxa2pcm_src_lim_ptr,d1
move.l cdxa_curhed,d0 ;次に該当するセクタを探す
bra @_2
@_1:
lea.l (2336,a1),a1
@_2:
cmpa.l d1,a1
beq @_8 ;該当するセクタがない
cmp.l (a1),d0
bne @_1
lea.l cdxa2pcm_buffer,a0
.if side=1
;ステレオ左
bsr decode_cdxa_stereo_left
.else
;ステレオ右
bsr decode_cdxa_stereo_right
.endif
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
lea.l cdxa2pcm_buffer,Asrc
lea.l (4032,Asrc),Alim
jmp (Ajmp)
@_8:
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
.endm
GET_DATA_1 .macro src,dat,tmp
move.w (src)+,dat
.endm
GET_DATA_2 .macro src,dat,tmp
move.w (src)+,dat
.endm
.irp %q,LQ,HQ,SQ
.align 4,$2048
preconv_sxa4_stereo_%q::
move.l a0,cdxa2pcm_dst_top_ptr
move.l a1,cdxa2pcm_src_top_ptr
move.l a1,cdxa2pcm_src_cur_ptr
move.l a2,cdxa2pcm_src_lim_ptr
PRECONV_STEREO_%q
movea.l cdxa2pcm_dst_top_ptr,a1
rts
.endm
;モノラル→モノラル
START_PRECONV_BUFFER .macro side
movem.l d0/a0-a1,-(sp)
lea.l cdxa2pcm_buffer,a0
move.l cdxa2pcm_src_top_ptr,a1 ;最初なので必ず該当するセクタになっている
bsr decode_cdxa_mono
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0/a0-a1
lea.l cdxa2pcm_buffer,Asrc
lea.l (8064,Asrc),Alim
movea.l cdxa2pcm_dst_top_ptr,Adst
.endm
LOOP_PRECONV_BUFFER .macro side
movem.l d0-d1/a0-a1,-(sp)
move.l cdxa2pcm_src_cur_ptr,a1
move.l cdxa2pcm_src_lim_ptr,d1
move.l cdxa_curhed,d0 ;次に該当するセクタを探す
bra @_2
@_1:
lea.l (2336,a1),a1
@_2:
cmpa.l d1,a1
beq @_8 ;該当するセクタがない
cmp.l (a1),d0
bne @_1
lea.l cdxa2pcm_buffer,a0
bsr decode_cdxa_mono
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
lea.l cdxa2pcm_buffer,Asrc
lea.l (8064,Asrc),Alim
jmp (Ajmp)
@_8:
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
.endm
GET_DATA_0 .macro src,dat,tmp
move.w (src)+,dat
.endm
.irp %q,LQ,HQ,SQ
.align 4,$2048
preconv_mxa4_mono_%q::
move.l a0,cdxa2pcm_dst_top_ptr
move.l a1,cdxa2pcm_src_top_ptr
move.l a1,cdxa2pcm_src_cur_ptr
move.l a2,cdxa2pcm_src_lim_ptr
PRECONV_MONO_%q
movea.l cdxa2pcm_dst_top_ptr,a1
rts
.endm
;ステレオ→モノラル
START_PRECONV_BUFFER .macro side
movem.l d0/a0-a1,-(sp)
lea.l cdxa2pcm_buffer,a0
move.l cdxa2pcm_src_top_ptr,a1 ;最初なので必ず該当するセクタになっている
.if 0
bsr decode_cdxa_stereo_left
lea.l (4032,a0),a0
bsr decode_cdxa_stereo_right
.else
bsr decode_cdxa_stereo_both
.endif
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0/a0-a1
lea.l cdxa2pcm_buffer,Asrc
.if 0
lea.l (4032,Asrc),Alim ;データは8064バイトあるが,Alimはleftの末尾を指す
.else
lea.l (8064,Asrc),Alim
.endif
movea.l cdxa2pcm_dst_top_ptr,Adst
.endm
LOOP_PRECONV_BUFFER .macro side
movem.l d0-d1/a0-a1,-(sp)
move.l cdxa2pcm_src_cur_ptr,a1
move.l cdxa2pcm_src_lim_ptr,d1
move.l cdxa_curhed,d0 ;次に該当するセクタを探す
bra @_2
@_1:
lea.l (2336,a1),a1
@_2:
cmpa.l d1,a1
beq @_8 ;該当するセクタがない
cmp.l (a1),d0
bne @_1
lea.l cdxa2pcm_buffer,a0
.if 0
bsr decode_cdxa_stereo_left
lea.l (4032,a0),a0
bsr decode_cdxa_stereo_right
.else
bsr decode_cdxa_stereo_both
.endif
lea.l (2336,a1),a1
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
lea.l cdxa2pcm_buffer,Asrc
.if 0
lea.l (4032,Asrc),Alim ;データは8064バイトあるが,Alimはleftの末尾を指す
.else
lea.l (8064,Asrc),Alim
.endif
jmp (Ajmp)
@_8:
move.l a1,cdxa2pcm_src_cur_ptr
movem.l (sp)+,d0-d1/a0-a1
.endm
GET_DATA_0 .macro src,dat,tmp
.if 0
move.w (4032,src),dat ;right
add.w (src)+,dat ;+left
.else
move.w (src)+,dat ;left
add.w (src)+,dat ;+right
.endif
bvc @skip
@over:
roxr.w #1,dat ;常にvc
bra @done
@skip:
asr.w #1,dat ;常にvc
@done:
.endm
.irp %q,LQ,HQ,SQ
.align 4,$2048
preconv_sxa4_mono_%q::
move.l a0,cdxa2pcm_dst_top_ptr
move.l a1,cdxa2pcm_src_top_ptr
move.l a1,cdxa2pcm_src_cur_ptr
move.l a2,cdxa2pcm_src_lim_ptr
PRECONV_MONO_%q
movea.l cdxa2pcm_dst_top_ptr,a1
rts
.endm
.bss
.align 4
cdxa2pcm_dst_top_ptr: .ds.l 1
cdxa2pcm_src_top_ptr: .ds.l 1
cdxa2pcm_src_cur_ptr: .ds.l 1
cdxa2pcm_src_lim_ptr: .ds.l 1
cdxa2pcm_buffer: .ds.b 8064
;----------------------------------------------------------------
;----------------------------------------------------------------
;PlayStationのCDXAファイル(.XA/.STR)の音声セクタのフォーマット
; 参考: xa2wave.c v1.2 (佐藤正徳氏作)
; xa2pcm.x v0.6 (ハリケーン氏作)
;
; CDXAファイルのセクタをYellowBook Mode2(2336bytes/sector)で読み込む
;
; Sector
; .ds.b 4 ;Header
; .ds.b 4 ;Header
; .ds.b 128*18 ;SoundGroup(g) g=0~17
; .ds.b 24 ;あまり
; (2336bytes)
;
; Header
; .ds.b 1 ;(Track内)Index
; .ds.b 1 ;Track
; .ds.b 1 ;DataType
; .ds.b 1 ;Mode
;
; (Track内)Index
; ほとんど$01
;
; Track
; .STRの音声トラックは$01,データによっては複数のトラックが存在する
;
; DataType
; $42,$48など 画像
; $64 音声
;
; Mode
; DataType=$64(音声)のとき
; bit0 0=Mono,1=Stereo
; bit2 0=37800Hz,1=18900Hz
;
; SoundGroup(g) g=0~17
; .ds.b 1*4 ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=0~3
; .ds.b 1*4 ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=0~3
; .ds.b 1*4 ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=4~7
; .ds.b 1*4 ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=4~7
; .ds.b 4*28 ;Sample(g,s) s=0~27
; (128bytes)
;
; Filter(g,u) g=0~17,u=0~7
; 0~3
;
; Range(g,u) g=0~17,u=0~7
; 0~12
;
; Sample(g,s) g=0~17,s=0~27
; .ds.b 1*4 ;(Unit(g,2n+1)のData(g,2n+1,s)<<4)+Unit(g,2n)のData(g,2n,s)
; n=0~3
; (4bytes)
;
; Data(g,u,s) g=0~17,u=0~7,s=0~27
; 0 0
; 1 1
; 2 2
; 3 3
; 4 4
; 5 5
; 6 6
; 7 7
; 8 -8
; 9 -7
; 10 -6
; 11 -5
; 12 -4
; 13 -3
; 14 -2
; 15 -1
;
; C1(f) f=0~3
; C1(0)=0.0 ($0000.0000)
; C1(1)=0.9375 ($0000.F000)
; C1(2)=1.796875 ($0001.CC00)
; C1(3)=1.53125 ($0001.8800)
;
; C2(f) f=0~3
; C2(0)=0.0 ($0000.0000)
; C2(1)=0.0 ($0000.0000)
; C2(2)=-0.8125 ($FFFF.3000)
; C2(3)=-0.859375 ($FFFF.2400)
;
; デコードアルゴリズム
;
; モノラルの場合
; n=0
; p(-2)=前回のp(4030)(初回は0)
; p(-1)=前回のp(4031)(初回は0)
; g=0~17
; u=0~7
; r=Range(g,u)
; f=Filter(g,u)
; s=0~27
; d=Data(g,u,s)
; if d>=8 then d=d-16
; p(n)=(d<<(12-r))+p(n-1)*C1(f)+p(n-2)*C2(f)
; n=n+1
; p(0~4031)を-32768~32767にクリッピングして整数化して出力する
;
; ステレオの場合(偶数Unitがleft,奇数Unitがright)
; n=0
; pl(-2)=前回のpl(2014)(初回は0)
; pl(-1)=前回のpl(2015)(初回は0)
; pr(-2)=前回のpr(2014)(初回は0)
; pr(-1)=前回のpr(2015)(初回は0)
; g=0~17
; u=0,2,4,6
; r=Range(g,u)
; f=Filter(g,u)
; s=0~27
; d=Data(g,u,s)
; if d>=8 then d=d-16
; pl(n)=(d<<(12-r))+pl(n-1)*C1(f)+pl(n-2)*C2(f)
; n=n+1
; u=1,3,5,7
; r=Range(g,u)
; f=Filter(g,u)
; s=0~27
; d=Data(g,u,s)
; if d>=8 then d=d-16
; pr(n)=(d<<(12-r))+pr(n-1)*C1(f)+pr(n-2)*C2(f)
; n=n+1
; pl(0~2015)がleft,pr(0~2015)がright
; それぞれ-32768~32767にクリッピングして整数化して出力する
;----------------------------------------------------------------
;----------------------------------------------------------------
;CDXAデコーダが使用するテーブルの初期化
; 偶数Unit用Rangeテーブル 2*256*13
; 奇数Unit用Rangeテーブル 2*256*13
; 高精度偶数Unit用Rangeテーブル 4*256*13
; 高精度奇数Unit用Rangeテーブル 4*256*13
; C1(1)/2テーブル 2*32768
; C1(2)/2テーブル 2*32768
; C1(3)/2テーブル 2*32768
; C2(2)/2テーブル 2*32768
; C2(3)/2テーブル 2*32768
; モノラル偶数Unit用Filterテーブル 16*256
; モノラル奇数Unit用Filterテーブル 16*256
; ステレオ偶数Unit(left)用Filterテーブル 16*256
; ステレオ奇数Unit(right)用Filterテーブル 16*256
; 高精度モノラル偶数Unit用Filterテーブル 8*256
; 高精度モノラル奇数Unit用Filterテーブル 8*256
; 高精度ステレオ偶数Unit(left)用Filterテーブル 8*256
; 高精度ステレオ奇数Unit(right)用Filterテーブル 8*256
.text
.align 4,$2048
init_cdxa_tables:
movem.l d1-d7/a0-a6,-(sp)
tst.b cdxa_tables_constructed
bne 98f
st.b cdxa_tables_constructed
move.l #(2*256*13)*2+(4*256*13)*2+(2*32768)*5+(16*256)*4+(8*256)*4,-(sp)
DOS _MALLOC
addq.l #4,sp
tst.l d0
bmi 90f ;メモリが確保できない
movea.l d0,a0
;----------------------------------------------------------------
;----------------------------------------------------------------
;偶数Unit用Rangeテーブルを作る
; データの順序は
; Range(11~-1)
; 上位4bit(0~15)
; 下位4bit(0~15)
; 設定の順序は
; 下位4bit(0~15) +2
; Range(11~-1) +2*256
; 上位4bit(0~15) +2*16
;<a0.l:バッファの先頭アドレス(align4)
; 2*256*13=6656bytes
move.l a0,even_range_table_ptr
clr.w d1
1: move.w d1,d0
moveq.l #13-1,d2
2: asr.w #1,d0
.irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
move.w d0,(2*16*n,a0)
.endm
lea.l (2*256,a0),a0
dbra d2,2b
lea.l (-2*256*13+2,a0),a0
add.w #1<<12,d1
bcc 1b
lea.l (-2*16+2*256*13,a0),a0
;----------------------------------------------------------------
;奇数Unit用Rangeテーブルを作る
; データの順序は
; Range(11~-1)
; 上位4bit(0~15)
; 下位4bit(0~15)
; 設定の順序は
; 上位4bit(0~15) +2*16
; Range(11~-1) +2*256
; 下位4bit(0~15) +2
;<a0.l:バッファの先頭アドレス(align4)
; 2*256*13=6656bytes
move.l a0,odd_range_table_ptr
clr.w d1
1: move.w d1,d0
moveq.l #13-1,d2
2: asr.w #1,d0
.irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
move.w d0,(2*n,a0)
.endm
lea.l (2*256,a0),a0
dbra d2,2b
lea.l (-2*256*13+2*16,a0),a0
add.w #1<<12,d1
bcc 1b
lea.l (-2*256+2*256*13,a0),a0
;----------------------------------------------------------------
;高精度偶数Unit用Rangeテーブルを作る
; データの順序は
; Range(12~0)
; 上位4bit(0~15)
; 下位4bit(0~15)
; 設定の順序は
; 下位4bit(0~15) +4
; Range(12~0) +4*256
; 上位4bit(0~15) +4*16
;<a0.l:バッファの先頭アドレス(align4)
; 4*256*13=13312bytes
move.l a0,hq_even_range_table_ptr
moveq.l #0,d1
1: move.l d1,d0
.if 1
asr.l #2,d0
.else
asr.l #8,d0
.endif
moveq.l #13-1,d2
2:
.irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
move.l d0,(4*16*n,a0)
.endm
asr.l #1,d0
lea.l (4*256,a0),a0
dbra d2,2b
lea.l (-4*256*13+4,a0),a0
add.l #1<<(12+16),d1
bcc 1b
lea.l (-4*16+4*256*13,a0),a0
;----------------------------------------------------------------
;高精度奇数Unit用Rangeテーブルを作る
; データの順序は
; Range(12~0)
; 上位4bit(0~15)
; 下位4bit(0~15)
; 設定の順序は
; 上位4bit(0~15) +4*16
; Range(12~0) +4*256
; 下位4bit(0~15) +4
;<a0.l:バッファの先頭アドレス(align4)
; 4*256*13=13312bytes
move.l a0,hq_odd_range_table_ptr
moveq.l #0,d1
1: move.l d1,d0
.if 1
asr.l #2,d0
.else
asr.l #8,d0
.endif
moveq.l #13-1,d2
2:
.irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
move.l d0,(4*n,a0)
.endm
asr.l #1,d0
lea.l (4*256,a0),a0
dbra d2,2b
lea.l (-4*256*13+4*16,a0),a0
add.l #1<<(12+16),d1
bcc 1b
lea.l (-4*256+4*256*13,a0),a0
;----------------------------------------------------------------
;----------------------------------------------------------------
movea.w #$7FFF,a1 ;a1=$00007FFF(正の値に加えて5捨6入するのに使う)
lea.l (1,a1),a2 ;a2=$00008000(負の値に加えて5捨6入するのに使う)
;----------------------------------------------------------------
;C1(1)/2テーブルを作る
; C1(1)=0.9375 ($0000.F000)
; p1*C1(1)/2 p1=-32768~32766(even)
;<a0.l:バッファの先頭アドレス(align4)
; 2*32768=65536bytes
;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
move.l #$0000F000,d3 ;$0000.F000/2*2=$0000.F000
move.l #$C4000000,d2 ;-32768*$0000.F000/2=$FFFFC400
move.w #16384/2-1,d4 ;-32768~-2(even)
4: move.l d2,d0
add.l d3,d2
add.l a2,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
move.l a0,c1_1_table_base_ptr
move.w #16384/2-1,d4 ;0~32766(even)
4: move.l d2,d0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a1,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
;----------------------------------------------------------------
;C1(2)/2テーブルを作る
; C1(2)=1.796875 ($0001.CC00)
; p1*C1(2)/2 p1=-32768~32766(even)
;<a0.l:バッファの先頭アドレス(align4)
; 2*32768=65536bytes
;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
move.l #$0001CC00,d3 ;$0001.CC00/2*2=$0001.CC00
move.l #$8D000000,d2 ;-32768*$0001.CC00/2=$FFFF8D00
move.w #16384/2-1,d4 ;-32768~-2(even)
4: move.l d2,d0
add.l d3,d2
add.l a2,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
move.l a0,c1_2_table_base_ptr
move.w #16384/2-1,d4 ;0~32766(even)
4: move.l d2,d0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a1,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
;----------------------------------------------------------------
;C1(3)/2テーブルを作る
; C1(3)=1.53125 ($0001.8800)
; p1*C1(3)/2 p1=-32768~32766(even)
;<a0.l:バッファの先頭アドレス(align4)
; 2*32768=65536bytes
;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
movea.w #$7FFF,a1
move.l #$00018800,d3 ;$0001.8800/2*2=$0001.8800
move.l #$9E000000,d2 ;-32768*$0001.8800/2=$FFFF9E00
move.w #16384/2-1,d4 ;-32768~-2(even)
4: move.l d2,d0
add.l d3,d2
add.l a2,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
move.l a0,c1_3_table_base_ptr
move.w #16384/2-1,d4 ;0~32766(even)
4: move.l d2,d0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a1,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
;----------------------------------------------------------------
;C2(2)/2テーブルを作る
; C2(2)=-0.8125 ($FFFF.3000)
; p2*C2(2)/2 p2=-32768~32766(even)
;<a0.l:バッファの先頭アドレス(align4)
; 2*32768=65536bytes
;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
movea.w #$7FFF,a1
move.l #$FFFF3000,d3 ;$FFFF.3000/2*2=$FFFF.3000
move.l #$34000000,d2 ;-32768*$FFFF.3000/2=$0000.3400
move.w #16384/2-1,d4 ;-32768~-2(even)
4: move.l d2,d0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a1,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
move.l a0,c2_2_table_base_ptr
move.l d2,d0 ;0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1 ;2
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
move.w #16382/2-1,d4 ;4~32766
4: move.l d2,d0
add.l d3,d2
add.l a2,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
;----------------------------------------------------------------
;C2(3)/2テーブルを作る
; C2(3)=-0.859375 ($FFFF.2400)
; p2*C2(3)/2 p2=-32768~32766(even)
;<a0.l:バッファの先頭アドレス(align4)
; 2*32768=65536bytes
;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
movea.w #$7FFF,a1
move.l #$FFFF2400,d3 ;$FFFF.2400/2*2=$FFFF.2400
move.l #$37000000,d2 ;-32768*$FFFF.2400/2=$0000.3700
move.w #16384/2-1,d4 ;-32768~2(even)
4: move.l d2,d0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a1,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
move.l a0,c2_3_table_base_ptr
move.l d2,d0 ;0
add.l d3,d2
add.l a1,d0 ;絶対値を5捨6入
move.l d2,d1 ;2
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
move.w #16382/2-1,d4 ;4~32766
4: move.l d2,d0
add.l d3,d2
add.l a2,d0 ;絶対値を5捨6入
move.l d2,d1
add.l d3,d2
add.l a2,d1 ;絶対値を5捨6入
swap.w d1
move.w d1,d0
move.l d0,(a0)+
dbra d4,4b
;----------------------------------------------------------------
;----------------------------------------------------------------
;モノラル偶数Unit用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; C1(f)/2テーブルのベース
; C2(f)/2テーブルのベース
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [even_range_table_ptr]+2*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C1(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 [c1_1_table_base_ptr]
; Filter=2 [c1_2_table_base_ptr]
; Filter=3 [c1_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C2(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 無効(絶対に使用されない)
; Filter=2 [c2_2_table_base_ptr]
; Filter=3 [c2_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_mono_filter_0
; Filter=1 cdxa_mono_filter_1
; Filter=2 cdxa_mono_filter_2
; Filter=3 cdxa_mono_filter_3
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 16*256=4096bytes
move.l a0,mono_even_filter_table_ptr
movea.l even_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
movea.l c1_1_table_base_ptr,a3
movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_0,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=1
movea.l a1,a2
; movea.l c1_1_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_1,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=2
movea.l a1,a2
movea.l c1_2_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_2,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=3
movea.l a1,a2
movea.l c1_3_table_base_ptr,a3
movea.l c2_3_table_base_ptr,a4
lea.l cdxa_mono_filter_3,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;モノラル奇数Unit用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; C1(f)/2テーブルのベース
; C2(f)/2テーブルのベース
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [odd_range_table_ptr]+2*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C1(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 [c1_1_table_base_ptr]
; Filter=2 [c1_2_table_base_ptr]
; Filter=3 [c1_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C2(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 無効(絶対に使用されない)
; Filter=2 [c2_2_table_base_ptr]
; Filter=3 [c2_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_mono_filter_0
; Filter=1 cdxa_mono_filter_1
; Filter=2 cdxa_mono_filter_2
; Filter=3 cdxa_mono_filter_3
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 16*256=4096bytes
move.l a0,mono_odd_filter_table_ptr
movea.l odd_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
movea.l c1_1_table_base_ptr,a3
movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_0,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=1
movea.l a1,a2
; movea.l c1_1_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_1,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=2
movea.l a1,a2
movea.l c1_2_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_mono_filter_2,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=3
movea.l a1,a2
movea.l c1_3_table_base_ptr,a3
movea.l c2_3_table_base_ptr,a4
lea.l cdxa_mono_filter_3,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;ステレオ偶数Unit(left)用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; C1(f)/2テーブルのベース
; C2(f)/2テーブルのベース
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [even_range_table_ptr]+2*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C1(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 [c1_1_table_base_ptr]
; Filter=2 [c1_2_table_base_ptr]
; Filter=3 [c1_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C2(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 無効(絶対に使用されない)
; Filter=2 [c2_2_table_base_ptr]
; Filter=3 [c2_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_stereo_filter_0
; Filter=1 cdxa_stereo_filter_1
; Filter=2 cdxa_stereo_filter_2
; Filter=3 cdxa_stereo_filter_3
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 16*256=4096bytes
move.l a0,stereo_even_filter_table_ptr
movea.l even_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
movea.l c1_1_table_base_ptr,a3
movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_0,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=1
movea.l a1,a2
; movea.l c1_1_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_1,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=2
movea.l a1,a2
movea.l c1_2_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_2,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=3
movea.l a1,a2
movea.l c1_3_table_base_ptr,a3
movea.l c2_3_table_base_ptr,a4
lea.l cdxa_stereo_filter_3,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;ステレオ奇数Unit(right)用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; C1(f)/2テーブルのベース
; C2(f)/2テーブルのベース
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [odd_range_table_ptr]+2*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C1(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 [c1_1_table_base_ptr]
; Filter=2 [c1_2_table_base_ptr]
; Filter=3 [c1_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; C2(f)/2テーブルのベース
; Filter=0 無効(絶対に使用されない)
; Filter=1 無効(絶対に使用されない)
; Filter=2 [c2_2_table_base_ptr]
; Filter=3 [c2_3_table_base_ptr]
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_stereo_filter_0
; Filter=1 cdxa_stereo_filter_1
; Filter=2 cdxa_stereo_filter_2
; Filter=3 cdxa_stereo_filter_3
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 16*256=4096bytes
move.l a0,stereo_odd_filter_table_ptr
movea.l odd_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
movea.l c1_1_table_base_ptr,a3
movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_0,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=1
movea.l a1,a2
; movea.l c1_1_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_1,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=2
movea.l a1,a2
movea.l c1_2_table_base_ptr,a3
; movea.l c2_2_table_base_ptr,a4
lea.l cdxa_stereo_filter_2,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
;Filter=3
movea.l a1,a2
movea.l c1_3_table_base_ptr,a3
movea.l c2_3_table_base_ptr,a4
lea.l cdxa_stereo_filter_3,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2-a5,(16*r,a0)
lea.l (2*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2-a5,(16*r,a0)
.endm
lea.l (16*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;----------------------------------------------------------------
;高精度モノラル偶数Unit用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [hq_even_range_table_ptr]+4*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_mono_filter_0_hq
; Filter=1 cdxa_mono_filter_1_hq
; Filter=2 cdxa_mono_filter_2_hq
; Filter=3 cdxa_mono_filter_3_hq
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 8*256=2048bytes
move.l a0,hq_mono_even_filter_table_ptr
movea.l hq_even_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
lea.l cdxa_mono_filter_0_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=1
movea.l a1,a2
lea.l cdxa_mono_filter_1_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=2
movea.l a1,a2
lea.l cdxa_mono_filter_2_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=3
movea.l a1,a2
lea.l cdxa_mono_filter_3_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;高精度モノラル奇数Unit用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [hq_odd_range_table_ptr]+4*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_mono_filter_0_hq
; Filter=1 cdxa_mono_filter_1_hq
; Filter=2 cdxa_mono_filter_2_hq
; Filter=3 cdxa_mono_filter_3_hq
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 8*256=2048bytes
move.l a0,hq_mono_odd_filter_table_ptr
movea.l hq_odd_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
lea.l cdxa_mono_filter_0_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=1
movea.l a1,a2
lea.l cdxa_mono_filter_1_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=2
movea.l a1,a2
lea.l cdxa_mono_filter_2_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=3
movea.l a1,a2
lea.l cdxa_mono_filter_3_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;高精度ステレオ偶数Unit(left)用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [hq_even_range_table_ptr]+4*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_stereo_filter_0_hq
; Filter=1 cdxa_stereo_filter_1_hq
; Filter=2 cdxa_stereo_filter_2_hq
; Filter=3 cdxa_stereo_filter_3_hq
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 8*256=2048bytes
move.l a0,hq_stereo_even_filter_table_ptr
movea.l hq_even_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
lea.l cdxa_stereo_filter_0_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=1
movea.l a1,a2
lea.l cdxa_stereo_filter_1_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=2
movea.l a1,a2
lea.l cdxa_stereo_filter_2_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=3
movea.l a1,a2
lea.l cdxa_stereo_filter_3_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
;高精度ステレオ奇数Unit(right)用Filterテーブルを作る
; データの順序は
; Filter(0~3,4~15は無効)
; Range(0~12,13~15は無効)
; Rangeテーブルの先頭
; Filterルーチン
; Rangeテーブルの先頭
; Range=0~12 [hq_odd_range_table_ptr]+4*256*Range
; Range=13~15 無効(データが未対応または壊れているとき参照される可能性がある)
; Filterルーチン
; Filter=0 cdxa_stereo_filter_0_hq
; Filter=1 cdxa_stereo_filter_1_hq
; Filter=2 cdxa_stereo_filter_2_hq
; Filter=3 cdxa_stereo_filter_3_hq
; Filter=4~15 無効(データが未対応または壊れているとき参照される可能性がある)
;<a0.l:バッファの先頭アドレス(align4)
; 8*256=2048bytes
move.l a0,hq_stereo_odd_filter_table_ptr
movea.l hq_odd_range_table_ptr,a1
moveq.l #4-1,d4
4:
;Filter=0
movea.l a1,a2
lea.l cdxa_stereo_filter_0_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=1
movea.l a1,a2
lea.l cdxa_stereo_filter_1_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=2
movea.l a1,a2
lea.l cdxa_stereo_filter_2_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
;Filter=3
movea.l a1,a2
lea.l cdxa_stereo_filter_3_hq,a5
.irp r,0,1,2,3,4,5,6,7,8,9,10,11
movem.l a2/a5,(8*r,a0)
lea.l (4*256,a2),a2
.endm
.irp r,12,13,14,15
movem.l a2/a5,(8*r,a0)
.endm
lea.l (8*16,a0),a0
dbra d4,4b
;----------------------------------------------------------------
98: moveq.l #0,d0
99: movem.l (sp)+,d1-d7/a0-a6
rts
90: moveq.l #-1,d0
bra 99b
;----------------------------------------------------------------
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(モノラル)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(8064)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_mono:
.if 1
cmpi.b #LOW_QUALITY,quality_level
bne decode_cdxa_mono_hq
.else
tst.b current_mpu_num
bne decode_cdxa_mono_hq
.endif
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.w left1,d0 ;1つ前
move.w left2,d1 ;2つ前
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,1,2,3,4,5,6,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
.if (u.and.1)=0
movea.l mono_even_filter_table_ptr,a5
.else
movea.l mono_odd_filter_table_ptr,a5
.endif
lsl.w #4,d6
movem.l (a5,d6.l),a2-a5 ;a2=Rangeテーブルの先頭
;a3=C1(f)/2テーブルのベース
;a4=C2(f)/2テーブルのベース
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.w d0,left1 ;1つ前
move.w d1,left2 ;2つ前
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(ステレオ左)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(4032)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_left:
.if 1
cmpi.b #LOW_QUALITY,quality_level
bne decode_cdxa_stereo_left_hq
.else
tst.b current_mpu_num
bne decode_cdxa_stereo_left_hq
.endif
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.w left1,d0 ;1つ前(left)
move.w left2,d1 ;2つ前(left)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,2,4,6
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
movea.l mono_even_filter_table_ptr,a5
lsl.w #4,d6
movem.l (a5,d6.l),a2-a5 ;a2=Rangeテーブルの先頭
;a3=C1(f)/2テーブルのベース
;a4=C2(f)/2テーブルのベース
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.w d0,left1 ;1つ前(left)
move.w d1,left2 ;2つ前(left)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(ステレオ右)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(4032)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_right:
.if 1
cmpi.b #LOW_QUALITY,quality_level
bne decode_cdxa_stereo_right_hq
.else
tst.b current_mpu_num
bne decode_cdxa_stereo_right_hq
.endif
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.w right1,d0 ;1つ前(right)
move.w right2,d1 ;2つ前(right)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,1,3,5,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
movea.l mono_odd_filter_table_ptr,a5
lsl.w #4,d6
movem.l (a5,d6.l),a2-a5 ;a2=Rangeテーブルの先頭
;a3=C1(f)/2テーブルのベース
;a4=C2(f)/2テーブルのベース
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.w d0,right1 ;1つ前(right)
move.w d1,right2 ;2つ前(right)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(ステレオ左右)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(8064)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_both:
.if 1
cmpi.b #LOW_QUALITY,quality_level
bne decode_cdxa_stereo_both_hq
.else
tst.b current_mpu_num
bne decode_cdxa_stereo_both_hq
.endif
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.w left1,d0 ;1つ前(left)
move.w left2,d1 ;2つ前(left)
move.w right1,d2 ;1つ前(right)
move.w right2,d3 ;2つ前(right)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,1,2,3,4,5,6,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
.if (u.and.1)=0
movea.l stereo_even_filter_table_ptr,a5
.else
movea.l stereo_odd_filter_table_ptr,a5
.endif
lsl.w #4,d6
movem.l (a5,d6.l),a2-a5 ;a2=Rangeテーブルの先頭
;a3=C1(f)/2テーブルのベース
;a4=C2(f)/2テーブルのベース
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.if (u.and.1)=0
addq.l #2,a0 ;left→right
.else
lea.l (-2+4*28,a0),a0
.endif
exg.l d0,d2
exg.l d1,d3
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.w d0,left1 ;1つ前(left)
move.w d1,left2 ;2つ前(left)
move.w d2,right1 ;1つ前(right)
move.w d3,right2 ;2つ前(right)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(高精度モノラル)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(8064)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_mono_hq:
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.l left1,d0 ;1つ前
move.l left2,d1 ;2つ前
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,1,2,3,4,5,6,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
.if (u.and.1)=0
movea.l hq_mono_even_filter_table_ptr,a5
.else
movea.l hq_mono_odd_filter_table_ptr,a5
.endif
lsl.w #3,d6
movem.l (a5,d6.l),a2/a5 ;a2=Rangeテーブルの先頭
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.l d0,left1 ;1つ前
move.l d1,left2 ;2つ前
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(高精度ステレオ左)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(4032)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_left_hq:
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.l left1,d0 ;1つ前(left)
move.l left2,d1 ;2つ前(left)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,2,4,6
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
movea.l hq_mono_even_filter_table_ptr,a5
lsl.w #3,d6
movem.l (a5,d6.l),a2/a5 ;a2=Rangeテーブルの先頭
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.l d0,left1 ;1つ前(left)
move.l d1,left2 ;2つ前(left)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(高精度ステレオ右)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(4032)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_right_hq:
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.l right1,d0 ;1つ前(right)
move.l right2,d1 ;2つ前(right)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,1,3,5,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
movea.l hq_mono_odd_filter_table_ptr,a5
lsl.w #3,d6
movem.l (a5,d6.l),a2/a5 ;a2=Rangeテーブルの先頭
;a3=C1(f)/2テーブルのベース
;a4=C2(f)/2テーブルのベース
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.l d0,right1 ;1つ前(right)
move.l d1,right2 ;2つ前(right)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;CDXA音声セクタデコーダ(高精度ステレオ左右)
;<a0.l:PCMバッファの先頭
; 2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
;<a1.l:CDXAデータセクタの先頭
; Mode2(2336bytes/sector)の先頭(typeの位置)
; +$00 |header||header||fr0123||fr0123|
; +$10 |fr4567||fr4567|| ADPCM
;>d0.l:生成されたPCMデータのバイト数(8064)
;>a0.l:PCMデータの先頭
;>a1.l:CDXAデータセクタの先頭
.text
.align 4,$2048
decode_cdxa_stereo_both_hq:
movem.l d1-d7/a0-a6,-(sp)
movea.l a1,a6 ;a6=Sectorの先頭
move.l left1,d0 ;1つ前(left)
move.l left2,d1 ;2つ前(left)
move.l right1,d2 ;1つ前(right)
move.l right2,d3 ;2つ前(right)
addq.l #8,a6 ;a6=SoundGroupの先頭
moveq.l #18-1,d7 ;g=0~17
7:
.irp u,0,1,2,3,4,5,6,7
moveq.l #0,d6
move.b (4+u,a6),d6 ;Filter,Range
.if (u.and.1)=0
movea.l hq_stereo_even_filter_table_ptr,a5
.else
movea.l hq_stereo_odd_filter_table_ptr,a5
.endif
lsl.w #3,d6
movem.l (a5,d6.l),a2/a5 ;a2=Rangeテーブルの先頭
;a5=Filterルーチン
lea.l (16+u/2,a6),a1 ;Dataの先頭
jsr (a5)
.if (u.and.1)=0
addq.l #2,a0 ;left→right
.else
lea.l (-2+4*28,a0),a0
.endif
exg.l d0,d2
exg.l d1,d3
.endm
lea.l (128,a6),a6 ;次のSoundGroupへ
dbra d7,7b
move.l d0,left1 ;1つ前(left)
move.l d1,left2 ;2つ前(left)
move.l d2,right1 ;1つ前(right)
move.l d3,right2 ;2つ前(right)
move.l a0,d0
movem.l (sp)+,d1-d7/a0-a6
sub.l a0,d0
rts
;----------------------------------------------------------------
;----------------------------------------------------------------
;モノラルFilter=0
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(+2*28)
.text
.align 4,$2048
cdxa_mono_filter_0:
s = 0
.rept 14
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w d1,d1
move.w d1,(a0)+
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w d0,d0
move.w d0,(a0)+
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;モノラルFilter=1
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(1)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(+2*28)
.text
.align 4,$2048
cdxa_mono_filter_1:
s = 0
.rept 14
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d0.w),d1 ;p1*C1(1)
add.w d1,d1
move.w d1,(a0)+
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(1)
add.w d0,d0
move.w d0,(a0)+
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;モノラルFilter=2
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(2)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;<a4.l:C2(2)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(+2*28)
;?d4
.text
.align 4,$2048
cdxa_mono_filter_2:
s = 0
.rept 9
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(2)
add.w (a4,d1.w),d4 ;p2*C2(2)
add.w d4,d4
move.w d4,(a0)+
s = s+1
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d4.w),d1 ;p1*C1(2)
add.w (a4,d0.w),d1 ;p2*C2(2)
add.w d1,d1
move.w d1,(a0)+
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(2)
add.w (a4,d4.w),d0 ;p2*C2(2)
add.w d0,d0
move.w d0,(a0)+
s = s+1
.endm
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(2)
add.w (a4,d1.w),d4 ;p2*C2(2)
add.w d4,d4
move.w d4,(a0)+
s = s+1
move.w d0,d1
move.w d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
;モノラルFilter=3
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(3)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;<a4.l:C2(3)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(+2*28)
;?d4
.if 1
;cdxa_mono_filter_3はcdxa_mono_filter_2とまったく同じなので省略
cdxa_mono_filter_3 equ cdxa_mono_filter_2
.else
.text
.align 4,$2048
cdxa_mono_filter_3:
s = 0
.rept 9
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(3)
add.w (a4,d1.w),d4 ;p2*C2(3)
add.w d4,d4
move.w d4,(a0)+
s = s+1
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d4.w),d1 ;p1*C1(3)
add.w (a4,d0.w),d1 ;p2*C2(3)
add.w d1,d1
move.w d1,(a0)+
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(3)
add.w (a4,d4.w),d0 ;p2*C2(3)
add.w d0,d0
move.w d0,(a0)+
s = s+1
.endm
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(3)
add.w (a4,d1.w),d4 ;p2*C2(3)
add.w d4,d4
move.w d4,(a0)+
s = s+1
move.w d0,d1
move.w d4,d0
.fail s<>28
rts
.endif
;----------------------------------------------------------------
;----------------------------------------------------------------
;ステレオFilter=0
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(変化しない)
.text
.align 4,$2048
cdxa_stereo_filter_0:
s = 0
.rept 14
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w d1,d1
move.w d1,(4*s,a0)
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w d0,d0
move.w d0,(4*s,a0)
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;ステレオFilter=1
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(1)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(変化しない)
.text
.align 4,$2048
cdxa_stereo_filter_1:
s = 0
.rept 14
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d0.w),d1 ;p1*C1(1)
add.w d1,d1
move.w d1,(4*s,a0)
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(1)
add.w d0,d0
move.w d0,(4*s,a0)
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;ステレオFilter=2
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(2)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;<a4.l:C2(2)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(変化しない)
;?d4
.text
.align 4,$2048
cdxa_stereo_filter_2:
s = 0
.rept 9
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(2)
add.w (a4,d1.w),d4 ;p2*C2(2)
add.w d4,d4
move.w d4,(4*s,a0)
s = s+1
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d4.w),d1 ;p1*C1(2)
add.w (a4,d0.w),d1 ;p2*C2(2)
add.w d1,d1
move.w d1,(4*s,a0)
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(2)
add.w (a4,d4.w),d0 ;p2*C2(2)
add.w d0,d0
move.w d0,(4*s,a0)
s = s+1
.endm
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(2)
add.w (a4,d1.w),d4 ;p2*C2(2)
add.w d4,d4
move.w d4,(4*s,a0)
s = s+1
move.w d0,d1
move.w d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
;ステレオFilter=3
;<d0.w:1つ前のPCMデータ
;<d1.w:2つ前のPCMデータ
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(11~-1)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 2*256*13=6656バイト
;<a3.l:C1(3)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;<a4.l:C2(3)/2テーブルのベース
; ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
;>d0.w:1つ前のPCMデータ
;>d1.w:2つ前のPCMデータ
;>a0.l:(変化しない)
;?d4
.if 1
;cdxa_stereo_filter_3はcdxa_stereo_filter_2とまったく同じなので省略
cdxa_stereo_filter_3 equ cdxa_stereo_filter_2
.else
.text
.align 4,$2048
cdxa_stereo_filter_3:
s = 0
.rept 9
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(3)
add.w (a4,d1.w),d4 ;p2*C2(3)
add.w d4,d4
move.w d4,(4*s,a0)
s = s+1
moveq.l #0,d1
move.b (4*s,a1),d1 ;Data=$?dまたは$d?
add.w d1,d1
move.w (a2,d1.w),d1 ;d<<(11-Range(u))
add.w (a3,d4.w),d1 ;p1*C1(3)
add.w (a4,d0.w),d1 ;p2*C2(3)
add.w d1,d1
move.w d1,(4*s,a0)
s = s+1
moveq.l #0,d0
move.b (4*s,a1),d0 ;Data=$?dまたは$d?
add.w d0,d0
move.w (a2,d0.w),d0 ;d<<(11-Range(u))
add.w (a3,d1.w),d0 ;p1*C1(3)
add.w (a4,d4.w),d0 ;p2*C2(3)
add.w d0,d0
move.w d0,(4*s,a0)
s = s+1
.endm
moveq.l #0,d4
move.b (4*s,a1),d4 ;Data=$?dまたは$d?
add.w d4,d4
move.w (a2,d4.w),d4 ;d<<(11-Range(u))
add.w (a3,d0.w),d4 ;p1*C1(3)
add.w (a4,d1.w),d4 ;p2*C2(3)
add.w d4,d4
move.w d4,(4*s,a0)
s = s+1
move.w d0,d1
move.w d4,d0
.fail s<>28
rts
.endif
;----------------------------------------------------------------
;----------------------------------------------------------------
;高精度モノラルFilter=0
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(+2*28)
;?d5
.text
.align 4,$2048
cdxa_mono_filter_0_hq:
FILTER .macro dx
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(a0)+
.endm
s = 0
.rept 14
FILTER d1
s = s+1
FILTER d0
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;高精度モノラルFilter=1
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(+2*28)
;?d5
.text
.align 4,$2048
cdxa_mono_filter_1_hq:
FILTER .macro dx,dy
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(1)=$0000.F000
move.l dy,d5
add.l d5,dx ;+$0001.0000
asr.l #4,d5 ; $0000.1000
sub.l d5,dx ;+$0000.F000
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(a0)+
.endm
s = 0
.rept 14
FILTER d1,d0
s = s+1
FILTER d0,d1
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;高精度モノラルFilter=2
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(+2*28)
;?d4-d5
.text
.align 4,$2048
cdxa_mono_filter_2_hq:
FILTER .macro dx,dy,dz
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(2)=$0001.CC00
move.l dy,d5 ; $0001.0000
add.l d5,dx ;+$0001.0000
add.l d5,dx ;+$0002.0000
asr.l #2,d5 ; $0000.4000
sub.l d5,dx ;+$0001.C000
asr.l #2,d5 ; $0000.1000
add.l d5,dx ;+$0001.D000
asr.l #2,d5 ; $0000.0400
sub.l d5,dx ;+$0001.CC00
;C2(2)=$FFFF.3000=-$0000.D000
sub.l dz,dx ;-$0001.0000
asr.l #2,dz ; $0000.4000
add.l dz,dx ;-$0000.C000
asr.l #2,dz ; $0000.1000
sub.l dz,dx ;-$0000.D000
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(a0)+
.endm
s = 0
.rept 9
FILTER d4,d0,d1
s = s+1
FILTER d1,d4,d0
s = s+1
FILTER d0,d1,d4
s = s+1
.endm
FILTER d4,d0,d1
s = s+1
move.l d0,d1
move.l d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
;高精度モノラルFilter=3
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(+2*28)
;?d4-d5
.text
.align 4,$2048
cdxa_mono_filter_3_hq:
FILTER .macro dx,dy,dz
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(3)=$0001.8800
move.l dy,d5 ; $0001.0000
add.l d5,dx ;+$0001.0000
asr.l #1,d5 ; $0000.8000
add.l d5,dx ;+$0001.8000
asr.l #4,d5 ; $0000.0800
add.l d5,dx ;+$0001.8800
;C2(3)=$FFFF.2400=-$0000.DC00
sub.l dz,dx ;-$0001.0000
asr.l #3,dz ; $0000.2000
add.l dz,dx ;-$0000.E000
asr.l #3,dz ; $0000.0400
add.l dz,dx ;-$0000.DC00
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(a0)+
.endm
s = 0
.rept 9
FILTER d4,d0,d1
s = s+1
FILTER d1,d4,d0
s = s+1
FILTER d0,d1,d4
s = s+1
.endm
FILTER d4,d0,d1
s = s+1
move.l d0,d1
move.l d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
;----------------------------------------------------------------
;高精度ステレオFilter=0
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(変化しない)
;?d5
.text
.align 4,$2048
cdxa_stereo_filter_0_hq:
FILTER .macro dx
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(4*s,a0)
.endm
s = 0
.rept 14
FILTER d1
s = s+1
FILTER d0
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;高精度ステレオFilter=1
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(変化しない)
;?d5
.text
.align 4,$2048
cdxa_stereo_filter_1_hq:
FILTER .macro dx,dy
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(1)=$0000.F000
move.l dy,d5
add.l d5,dx ;+$0001.0000
asr.l #4,d5 ; $0000.1000
sub.l d5,dx ;+$0000.F000
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(4*s,a0)
.endm
s = 0
.rept 14
FILTER d1,d0
s = s+1
FILTER d0,d1
s = s+1
.endm
.fail s<>28
rts
;----------------------------------------------------------------
;高精度ステレオFilter=2
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(変化しない)
;?d4-d5
.text
.align 4,$2048
cdxa_stereo_filter_2_hq:
FILTER .macro dx,dy,dz
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(2)=$0001.CC00
move.l dy,d5 ; $0001.0000
add.l d5,dx ;+$0001.0000
add.l d5,dx ;+$0002.0000
asr.l #2,d5 ; $0000.4000
sub.l d5,dx ;+$0001.C000
asr.l #2,d5 ; $0000.1000
add.l d5,dx ;+$0001.D000
asr.l #2,d5 ; $0000.0400
sub.l d5,dx ;+$0001.CC00
;C2(2)=$FFFF.3000=-$0000.D000
sub.l dz,dx ;-$0001.0000
asr.l #2,dz ; $0000.4000
add.l dz,dx ;-$0000.C000
asr.l #2,dz ; $0000.1000
sub.l dz,dx ;-$0000.D000
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(4*s,a0)
.endm
s = 0
.rept 9
FILTER d4,d0,d1
s = s+1
FILTER d1,d4,d0
s = s+1
FILTER d0,d1,d4
s = s+1
.endm
FILTER d4,d0,d1
s = s+1
move.l d0,d1
move.l d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
;高精度ステレオFilter=3
;<d0.l:1つ前のPCMデータ<<14
;<d1.l:2つ前のPCMデータ<<14
;<a0.l:PCMバッファの位置
;<a1.l:Sample(0)のDataの位置
;<a2.l:現在のRangeテーブル(12~0)
; 偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
; 残りのビットを無視するような構造のテーブル
; 4*256*13=13312バイト
;>d0.l:1つ前のPCMデータ<<14
;>d1.l:2つ前のPCMデータ<<14
;>a0.l:(変化しない)
;?d4-d5
.text
.align 4,$2048
cdxa_stereo_filter_3_hq:
FILTER .macro dx,dy,dz
moveq.l #0,dx
move.b (4*s,a1),dx ;Data=$?dまたは$d?
add.w dx,dx
add.w dx,dx
move.l (a2,dx.w),dx ;d<<(12-Range(u))
;C1(3)=$0001.8800
move.l dy,d5 ; $0001.0000
add.l d5,dx ;+$0001.0000
asr.l #1,d5 ; $0000.8000
add.l d5,dx ;+$0001.8000
asr.l #4,d5 ; $0000.0800
add.l d5,dx ;+$0001.8800
;C2(3)=$FFFF.2400=-$0000.DC00
sub.l dz,dx ;-$0001.0000
asr.l #3,dz ; $0000.2000
add.l dz,dx ;-$0000.E000
asr.l #3,dz ; $0000.0400
add.l dz,dx ;-$0000.DC00
;
move.l dx,d5
.if 1
asl.l #2,d5
swap.w d5
.else
asr.l #8,d5
.endif
move.w d5,(4*s,a0)
.endm
s = 0
.rept 9
FILTER d4,d0,d1
s = s+1
FILTER d1,d4,d0
s = s+1
FILTER d0,d1,d4
s = s+1
.endm
FILTER d4,d0,d1
s = s+1
move.l d0,d1
move.l d4,d0
.fail s<>28
rts
;----------------------------------------------------------------
.data
cdxa_tables_constructed: .dc.b 0 ;-1=テーブルが初期化された
.bss
.align 4
even_range_table_ptr: .ds.l 1 ;偶数Unit用のRangeテーブルの先頭
odd_range_table_ptr: .ds.l 1 ;奇数Unit用のRangeテーブルの先頭
hq_even_range_table_ptr: .ds.l 1 ;高精度偶数Unit用のRangeテーブルの先頭
hq_odd_range_table_ptr: .ds.l 1 ;高精度奇数Unit用のRangeテーブルの先頭
c1_1_table_base_ptr: .ds.l 1 ;C1(1)/2テーブルのベース
c1_2_table_base_ptr: .ds.l 1 ;C1(2)/2テーブルのベース
c1_3_table_base_ptr: .ds.l 1 ;C1(3)/2テーブルのベース
c2_2_table_base_ptr: .ds.l 1 ;C2(2)/2テーブルのベース
c2_3_table_base_ptr: .ds.l 1 ;C2(3)/2テーブルのベース
mono_even_filter_table_ptr: .ds.l 1 ;偶数Unit用Filterテーブルの先頭
mono_odd_filter_table_ptr: .ds.l 1 ;奇数Unit用Filterテーブルの先頭
stereo_even_filter_table_ptr: .ds.l 1 ;偶数Unit(left)用Filterテーブルの先頭
stereo_odd_filter_table_ptr: .ds.l 1 ;奇数Unit(right)用Filterテーブルの先頭
hq_mono_even_filter_table_ptr: .ds.l 1 ;高精度偶数Unit用Filterテーブルの先頭
hq_mono_odd_filter_table_ptr: .ds.l 1 ;高精度奇数Unit用Filterテーブルの先頭
hq_stereo_even_filter_table_ptr: .ds.l 1 ;高精度偶数Unit(left)用Filterテーブルの先頭
hq_stereo_odd_filter_table_ptr: .ds.l 1 ;高精度奇数Unit(right)用Filterテーブルの先頭
;----------------------------------------------------------------
;----------------------------------------------------------------
;xxデータの前処理(xxデータをOPMのTLの並びに変換する)
;<a0.l:出力バッファの先頭
;<a1.l:入力データの先頭(該当するセクタの先頭)
;<a2.l:入力データの末尾+1
;>a0.l:出力データの末尾+1
;>a1.l:出力データの先頭
;?d1-d7/a2-a6
.text
;モノラル→モノラル
START_PRECONV_BUFFER .macro side
lea.l xx2pcm_buffer,Asrc
move.l d0,-(sp)
movem.l a0-a2,-(sp)
movea.l Asrc,a0
movea.l xx2pcm_src_top_ptr,a1
move.l xx2pcm_src_lim_ptr,d0
lea.l (2048,a1),a2
cmpa.l d0,a2
bls @f
movea.l d0,a2
@@: bsr decode_xx_mono
move.l a1,xx2pcm_src_cur_ptr
move.l a0,d0
movem.l (sp)+,a0-a2
movea.l d0,Alim
move.l (sp)+,d0
movea.l xx2pcm_dst_top_ptr,Adst
.endm
LOOP_PRECONV_BUFFER .macro side
lea.l xx2pcm_buffer,Asrc
move.l d0,-(sp)
movem.l a0-a2,-(sp)
movea.l Asrc,a0
movea.l xx2pcm_src_cur_ptr,a1
move.l xx2pcm_src_lim_ptr,d0
lea.l (2048,a1),a2
cmpa.l d0,a2
bls @f
movea.l d0,a2
@@: bsr decode_xx_mono
move.l a1,xx2pcm_src_cur_ptr
move.l a0,d0
movem.l (sp)+,a0-a2
movea.l d0,Alim
move.l (sp)+,d0
cmpa.l Alim,Asrc
bhs @f
jmp (Ajmp)
@@:
.endm
GET_DATA_0 .macro src,dat,tmp
move.w (src)+,dat
.endm
.irp %q,LQ,HQ,SQ
.align 4,$2048
preconv_sxx4_stereo_%q::
preconv_mxx4_mono_%q::
preconv_sxx4_mono_%q::
move.l a0,xx2pcm_dst_top_ptr
move.l a1,xx2pcm_src_top_ptr
move.l a1,xx2pcm_src_cur_ptr
move.l a2,xx2pcm_src_lim_ptr
PRECONV_MONO_%q
movea.l xx2pcm_dst_top_ptr,a1
rts
.endm
.bss
.align 4
xx2pcm_dst_top_ptr: .ds.l 1
xx2pcm_src_top_ptr: .ds.l 1
xx2pcm_src_cur_ptr: .ds.l 1
xx2pcm_src_lim_ptr: .ds.l 1
xx2pcm_buffer: .ds.b 7168 ;2048/16*28*2=7168
;----------------------------------------------------------------
;xxデータのデコード(モノラル)
;<a0.l:PCMバッファの先頭
;<a1.l:xxデータの先頭
;<a2.l:xxデータの末尾+1
; xxデータのサイズは16の倍数にすること
;>a0.l:PCMデータの末尾+1
;>a1.l:xxデータの末尾+1
.text
.align 4,$2048
decode_xx_mono:
movem.l d0-d7/a3,-(sp)
move.l left1,d3 ;1つ前
move.l left2,d4 ;2つ前
bra 19f
10:
moveq.l #0,d0
move.b (a1)+,d0 ;Filter,Range
cmpi.b #$07,(a1)+
bne 2f
moveq.l #0,d1
.rept 28/2
move.l d1,(a0)+
.endm
lea.l (-1-1+16,a1),a1
bra 19f
2:
moveq.l #$0F,d2
and.w d0,d2 ;Range
sub.w d2,d0 ;Filter<<4
addq.w #4,d2 ;Range+4
lsr.w #2,d0 ;Filter<<2
lea.l xx_table,a3
adda.l d0,a3
move.w (a3)+,d6 ;C1(f)
move.w (a3)+,d7 ;C2(f)
FILTER .macro t,dx,dy,dz
.if t=0
moveq.l #$0F,dx
and.b (a1),dx
.else
moveq.l #0,dx
move.b (a1)+,dx
lsr.b #4,dx
.endif
ror.l #4,dx
asr.l d2,dx ;d<<(28-(Range+4))=d<<(12-Range+12)
movea.l dy,a3
move.l dy,d0
bpl @f
neg.l d0
@@: move.l d0,d1
; d0 d1
mulu.w d6,d0 ; mid|low
swap.w d1 ; mid|low
mulu.w d6,d1 ; mid|low high|mid highは最大6ビット
swap.w d0 ; low|mid high|mid
add.w d0,d1 ; low| ? high|mid x=midの繰り上がり
clr.w d0 ; low| 0 high|mid x=midの繰り上がり
swap.w d1 ; low| 0 mid|high x=midの繰り上がり
addx.w d0,d1 ; low| 0 mid|high low,mid,highとも確定
swap.w d0 ; 0 |low mid|high
and.w #-64,d0 ; 0 |low mid|high lowの下位6ビットを切り捨てる
or.l d1,d0 ; mid|low|high
ror.l #6,d0 ; high|mid|low
move.l a3,d1
bpl @f
neg.l d0
@@:
add.l d0,dx ;1つ前×C1(f)
movea.l dz,a3
move.l dz,d0
bpl @f
neg.l d0
@@: move.l d0,d1
; d0 d1
mulu.w d7,d0 ; mid|low
swap.w d1 ; mid|low
mulu.w d7,d1 ; mid|low high|mid highは最大6ビット
swap.w d0 ; low|mid high|mid
add.w d0,d1 ; low| ? high|mid x=midの繰り上がり
clr.w d0 ; low| 0 high|mid x=midの繰り上がり
swap.w d1 ; low| 0 mid|high x=midの繰り上がり
addx.w d0,d1 ; low| 0 mid|high low,mid,highとも確定
swap.w d0 ; 0 |low mid|high
and.w #-64,d0 ; 0 |low mid|high lowの下位6ビットを切り捨てる
or.l d1,d0 ; mid|low|high
ror.l #6,d0 ; high|mid|low
move.l a3,d1
bpl @f
neg.l d0
@@:
sub.l d0,dx ;2つ前×C2(f)
move.l dx,d0
asl.l #4,d0
swap.w d0
move.w d0,(a0)+
.endm
.rept 4
FILTER 0,d5,d3,d4
FILTER 1,d4,d5,d3
FILTER 0,d3,d4,d5
FILTER 1,d5,d3,d4
FILTER 0,d4,d5,d3
FILTER 1,d3,d4,d5
.endm
FILTER 0,d5,d3,d4
FILTER 1,d4,d5,d3
FILTER 0,d3,d4,d5
FILTER 1,d5,d3,d4
move.l d3,d4
move.l d5,d3
19: cmpa.l a2,a1
blo 10b
move.l d3,left1 ;1つ前
move.l d4,left2 ;2つ前
movem.l (sp)+,d0-d7/a3
rts
.data
.align 4
xx_table:: .dcb.w 2*16,255 ;C1(f),-C2(f)